package ch.fhnw.qualiscan.core;

import java.util.ArrayList;
import java.util.Iterator;

import ch.fhnw.qualiscan.AppObject;
import ch.fhnw.qualiscan.core.db.HibernateSession;
import ch.fhnw.qualiscan.core.debug.SessionSetter;
import ch.fhnw.qualiscan.core.helpers.SessionHelper;
import ch.fhnw.qualiscan.core.helpers.TextHelper;
import ch.fhnw.qualiscan.core.helpers.UserSession;
import ch.fhnw.qualiscan.core.libraries.ComponentLib;
import ch.fhnw.qualiscan.core.libraries.ModalLib;
import ch.fhnw.qualiscan.core.libraries.UrlLib;

import com.vaadin.ui.Component;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
import com.vaadin.ui.Window;

import eu.livotov.tpt.TPTApplication;

/**
 * Abstract class for all pages. All pages need to inherit from this class.
 * @author Kevin Mettenberger, Benjamin Groehbiel
 *
 */
@SuppressWarnings("serial")
public abstract class Page extends Panel { 
	
	public ArrayList<LayoutComponent> components = new ArrayList<LayoutComponent>();
	
	public ArrayList<String> neededPermissions = new ArrayList<String>();
	
	public TextHelper textHelper;
	
	public TabSheet tabSheet;
	
	public UserSession userSession;
	
	public HibernateSession hibernateSession;
	
	public SessionHelper sessionHelper;
	
	public ComponentLib componentLib;
	
	public UrlLib urlLib;
	
	public AppObject dataObject;
	
	public ModalLib modalLib;
	
	public boolean changeTab = true;
	
	SelectedTabChangeListener tabListener = new SelectedTabChangeListener() {
		private static final long serialVersionUID = 1L;
		public void selectedTabChange(SelectedTabChangeEvent event) {
			if (changeTab == false) {
				Iterator<Component> iterator = tabSheet.getComponentIterator();
				int i = 0;
				while(iterator.hasNext()) {
					Component c = (Component) iterator.next();
					if(c == event.getTabSheet().getSelectedTab()) {
						urlLib.setTab(i);
					}
					i++;
				}
			}
			changeTab = false;
		}
		
    };
	
	/**
	 * Constructor; setting the needed permissions.
	 */
	public Page() {
		//TODO: outcomment in development mode
		//userSession = new SessionSetter().createUserSession(48, 1);
		
		// several helpers
		textHelper = new TextHelper();
		hibernateSession = new HibernateSession();
		dataObject = (AppObject) TPTApplication.getCurrentApplication().getMainWindow().getData();
		urlLib = dataObject.getUrlLib();
		componentLib = new ComponentLib();
		modalLib = new ModalLib();
		
		setNeededPermissions();	
	}
	
	/**
	 * Called by LoaderLib if permission was granted. Loading all necessary functions, helpers and so on.
	 */
	public void init() {
		sessionHelper = new SessionHelper();
		
		//TODO: Outcomment on production site
		userSession = sessionHelper.getUserSession();

		// modal pages
		modalLib.closeModal();
		
		// each page contains a tabsheet
		tabSheet = new TabSheet();
		tabSheet.addListener(tabListener);
		tabSheet.setWidth("100%");
		tabSheet.setHeight("");
		
		// handling the components
		initComponents();
		
		componentLib.updateRightSidebar(components);


		//
		initModelsAndHelpers();
		
		// layout
		initBuildLayout();
		TPTApplication.getCurrentApplication().getMainWindow().setScrollTop(0);
	}
	
	public void initBuildLayout() {
		buildLayout();
	}
	
	
	/**
	 * Function to change the selected tab in a page, gets called when the second fragment changes.
	 * @param tab number of the tab, starting with 0 (left)
	 */ 
	public void changeTab(int tab) {

		changeTab = true;

		Iterator<Component> iterator = tabSheet.getComponentIterator();
		int i = 0;
		
		while (iterator.hasNext()) {
			Component c = (Component) iterator.next();
			
			if(tab == i) {
				tabSheet.setSelectedTab(c);
			}
			
			i++;
		}
		
	}
	
	/**
	 * 
	 * @param modal Window you would like to open in a modal box.
	 * @see ch.fhnw.qualiscan.application.modals
	 */
	public void openModal(Window modal) {
		modalLib.openModal(modal);
	}
	
	/**
	 * Concrete layout implementation with ui elements
	 */
	public abstract void buildLayout();
	
	/**
	 * Defines the permissions a user must have to display this page.
	 * If you leave the neededPermissions ArrayList empty, then no permissions are needed to open this controller.
	 */
	public abstract void setNeededPermissions();
	
	/**
	 * Initializes the models and helpers needed in the page.
	 */
	public abstract void initModelsAndHelpers();
	
	/**
	 * In this function you have to load the components you would like to load for this view.
	 * components.add(LayoutComponent)
	 * @see ch.fhnw.qualiscan.core.LayoutComponent
	 * @see ch.fhnw.qualiscan.core.libraries.ComponentLib
	 */
	public abstract void initComponents();
	
	/**
	 * gets called by UrlLib when the second parameter changes.
	 * @param secondParameter number of the current tab
	 */
	public void secondParameterChanged(int secondParameter) {
		changeTab(secondParameter);
	}
	
	/**
	 * gets called by UrlLib when the third parameter changes.
	 * @param currentUrl value (normally Id)
	 */
	public abstract void thirdParameterChanged(String currentUrl);
	
}